From 87ade57ac4df94bd9d55a2402dcfd3b834865a0f Mon Sep 17 00:00:00 2001 From: "leendert@watson.ibm.com[kaf24]" Date: Sat, 28 May 2005 15:21:07 +0000 Subject: [PATCH] bitkeeper revision 1.1585 (42988c63d2BDHoRycJzKDjIR50X5Sw) [PATCH] [PATCH] VMX world switch does not handle all cases The latest world switch modification does not handle all cases. Specifically, when a partition enables CR0.PG|CR0.PE and performs a world switch at the the same time. The patch below handles this case. Signed-Off-By: Leendert van Doorn --- xen/arch/x86/vmx.c | 54 +++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/xen/arch/x86/vmx.c b/xen/arch/x86/vmx.c index eaa73de5a4..895c8c11ce 100644 --- a/xen/arch/x86/vmx.c +++ b/xen/arch/x86/vmx.c @@ -744,8 +744,8 @@ static int vmx_set_cr0(unsigned long value) __vmwrite(CR0_READ_SHADOW, value); VMX_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx\n", value); - if ((value & X86_CR0_PE) && (value & X86_CR0_PG) - && !paging_enabled) { + + if ((value & X86_CR0_PE) && (value & X86_CR0_PG) && !paging_enabled) { /* * The guest CR3 must be pointing to the guest physical. */ @@ -775,33 +775,39 @@ static int vmx_set_cr0(unsigned long value) */ VMX_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx, mfn = %lx", d->arch.arch_vmx.cpu_cr3, mfn); - } else { - if ((value & X86_CR0_PE) == 0) { - __vmread(GUEST_EIP, &eip); - VMX_DBG_LOG(DBG_LEVEL_1, "Disabling CR0.PE at %%eip 0x%lx\n", eip); - if (vmx_assist(d, VMX_ASSIST_INVOKE)) { - set_bit(VMX_CPU_STATE_ASSIST_ENABLED, - &d->arch.arch_vmx.cpu_state); - __vmread(GUEST_EIP, &eip); - VMX_DBG_LOG(DBG_LEVEL_1, - "Transfering control to vmxassist %%eip 0x%lx", eip); - return 0; /* do not update eip! */ - } - } else if (test_bit(VMX_CPU_STATE_ASSIST_ENABLED, - &d->arch.arch_vmx.cpu_state)) { + } + + /* + * VMX does not implement real-mode virtualization. We emulate + * real-mode by performing a world switch to VMXAssist whenever + * a partition disables the CR0.PE bit. + */ + if ((value & X86_CR0_PE) == 0) { + __vmread(GUEST_EIP, &eip); + VMX_DBG_LOG(DBG_LEVEL_1, + "Disabling CR0.PE at %%eip 0x%lx\n", eip); + if (vmx_assist(d, VMX_ASSIST_INVOKE)) { + set_bit(VMX_CPU_STATE_ASSIST_ENABLED, &d->arch.arch_vmx.cpu_state); __vmread(GUEST_EIP, &eip); VMX_DBG_LOG(DBG_LEVEL_1, - "Enabling CR0.PE at %%eip 0x%lx", eip); - if (vmx_assist(d, VMX_ASSIST_RESTORE)) { - clear_bit(VMX_CPU_STATE_ASSIST_ENABLED, + "Transfering control to vmxassist %%eip 0x%lx\n", eip); + return 0; /* do not update eip! */ + } + } else if (test_bit(VMX_CPU_STATE_ASSIST_ENABLED, + &d->arch.arch_vmx.cpu_state)) { + __vmread(GUEST_EIP, &eip); + VMX_DBG_LOG(DBG_LEVEL_1, + "Enabling CR0.PE at %%eip 0x%lx\n", eip); + if (vmx_assist(d, VMX_ASSIST_RESTORE)) { + clear_bit(VMX_CPU_STATE_ASSIST_ENABLED, &d->arch.arch_vmx.cpu_state); - __vmread(GUEST_EIP, &eip); - VMX_DBG_LOG(DBG_LEVEL_1, - "Restoring to %%eip 0x%lx", eip); - return 0; /* do not update eip! */ - } + __vmread(GUEST_EIP, &eip); + VMX_DBG_LOG(DBG_LEVEL_1, + "Restoring to %%eip 0x%lx\n", eip); + return 0; /* do not update eip! */ } } + return 1; } -- 2.30.2